using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading;

namespace SDK.Scripts.Utils
{
	public class HttpClient
	{
		public struct WebData
		{
			public bool isSuccess;

			public string msg;

			public string statedesc;

			public string param;
		}

		public delegate void WebCallBack(WebData data);

		public class RequestState
		{
			public string url;

			public string param;

			public HttpWebRequest request;

			public WebCallBack webCallBack;

			public ManualResetEvent doDone;

			public RegisteredWaitHandle waitHandle;

			public bool isTimeOut;

			public RequestState()
			{
				request = null;
				webCallBack = null;
				url = string.Empty;
				doDone = new ManualResetEvent(initialState: false);
				waitHandle = null;
				param = string.Empty;
				isTimeOut = false;
			}
		}

		private static Dictionary<string, string> reqDic;

		public static void Request(string url, string param, WebCallBack webCallBack, string type = "GET", bool isTimeOut = true, int timeOut = 10)
		{
			if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
			{
				ServicePointManager.ServerCertificateValidationCallback = ((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => true);
				ServicePointManager.SecurityProtocol = (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls);
			}
			Common.SafeCall(delegate
			{
				WebData data;
				if (string.IsNullOrEmpty(url) || url.IndexOf("?") == 0)
				{
					if (webCallBack != null)
					{
						data.isSuccess = false;
						data.msg = string.Empty;
						data.param = param;
						data.statedesc = string.Empty;
						webCallBack(data);
					}
				}
				else
				{
					if (reqDic == null)
					{
						reqDic = new Dictionary<string, string>();
						reqDic[url] = "1";
					}
					else
					{
						if (reqDic.ContainsKey(url))
						{
							Debuger.Log("已经存在 放弃 " + url);
							return;
						}
						reqDic[url] = "1";
					}
					HttpWebRequest httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
					RequestState requestState = new RequestState
					{
						request = httpWebRequest,
						webCallBack = webCallBack,
						url = url,
						param = param,
						isTimeOut = false
					};
					if (isTimeOut)
					{
						requestState.waitHandle = ThreadPool.RegisterWaitForSingleObject(requestState.doDone, TimeoutCallback, requestState, timeOut * 1000, executeOnlyOnce: true);
					}
					httpWebRequest.BeginGetResponse(delegate(IAsyncResult ar)
					{
						Common.SafeCall(delegate
						{
							Debuger.LogDebug("request response");
							Common.ChildThreadCall(delegate
							{
								RequestState requestState2 = ar.AsyncState as RequestState;
								if (requestState2.waitHandle != null)
								{
									requestState2.waitHandle.Unregister(requestState2.doDone);
								}
								HttpWebRequest request = requestState2.request;
								if (request == null)
								{
									Debuger.LogError("request is null");
								}
								else
								{
									if (reqDic != null && reqDic.ContainsKey(requestState2.url))
									{
										reqDic.Remove(requestState2.url);
									}
									try
									{
										if (requestState2.isTimeOut)
										{
											Debuger.LogDebug("已经超时 丢弃本次响应 " + url);
										}
										else
										{
											HttpWebResponse httpWebResponse = request.EndGetResponse(ar) as HttpWebResponse;
											if (httpWebResponse.StatusCode == HttpStatusCode.OK)
											{
												string msg = string.Empty;
												using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
												{
													msg = streamReader.ReadToEnd();
												}
												if (webCallBack != null)
												{
													data.isSuccess = true;
													data.msg = msg;
													data.param = requestState2.param;
													data.statedesc = httpWebResponse.StatusDescription;
													webCallBack(data);
												}
											}
											else
											{
												data.isSuccess = false;
												data.msg = string.Empty;
												data.param = requestState2.param;
												data.statedesc = httpWebResponse.StatusDescription;
												webCallBack(data);
												Debuger.LogError("HttpStatusCode = " + httpWebResponse.StatusCode);
											}
											httpWebResponse.Close();
										}
									}
									catch (WebException ex)
									{
										if (webCallBack != null)
										{
											data.isSuccess = false;
											data.msg = string.Empty;
											data.param = requestState2.param;
											data.statedesc = "WebException " + ex.Message;
											webCallBack(data);
										}
										Debuger.LogError("request maybe has abort " + url + "," + ex.Message);
									}
									catch (ThreadAbortException ex2)
									{
										Debuger.LogError("ThreadAbortException " + url + "," + ex2.Message);
									}
								}
							});
						});
					}, requestState);
				}
			});
		}

		private static void TimeoutCallback(object state, bool timedOut)
		{
			Common.SafeCall(delegate
			{
				if (timedOut)
				{
					RequestState requestState = state as RequestState;
					HttpWebRequest request = requestState.request;
					if (request != null)
					{
						Debuger.LogDebug("req web timeout ,url " + requestState.url);
						requestState.waitHandle.Unregister(requestState.doDone);
						WebCallBack webCallBack = requestState.webCallBack;
						if (webCallBack != null)
						{
							WebData data = default(WebData);
							data.isSuccess = false;
							data.msg = string.Empty;
							data.param = requestState.param;
							data.statedesc = string.Empty;
							webCallBack(data);
						}
						requestState.isTimeOut = true;
						request.Abort();
					}
					else
					{
						Debuger.LogError("TimeoutCallback request is null");
					}
				}
			});
		}
	}
}
